package study.translation.interpreter;

public class RealNumber implements Number
{
    private static final double EPSILON = 0.00001;

    private double value;

    public RealNumber( double value )
    {
        this.value = value;
    }

    public double getValue()
    {
        return value;
    }

    public Number add( Number n )
    {
        if( n instanceof ComplexNumber )
        {
            ComplexNumber c = ( ComplexNumber )n;
            return new ComplexNumber( new RealNumber( getValue() + c.getRe().getValue() ), c.getIm() );
        }
        else
        {
            return new RealNumber( getValue() + ( ( RealNumber )n ).getValue() );
        }
    }

    public Number sub( Number n )
    {
        return add( n.changeSign() );
    }

    public Number mul( Number n )
    {
        if( n instanceof ComplexNumber )
        {
            return new ComplexNumber( this ).mul( n );
        }
        else
        {
            return new RealNumber( getValue() * ( ( RealNumber )n ).getValue() );
        }
    }

    public Number div( Number n )
    {
        if( n instanceof ComplexNumber )
        {
            return new ComplexNumber( this ).div( n );
        }
        else
        {
            return new RealNumber( getValue() / ( ( RealNumber )n ).getValue() );
        }
    }

    public Number changeSign()
    {
        return new RealNumber( -getValue() );
    }

    public boolean equals( Number n )
    {
        if( n instanceof ComplexNumber )
        {
            ComplexNumber c = ( ComplexNumber )n;
            return ( c.getIm().equals( new RealNumber( 0 ) ) && equals( c.getRe() ) );
        }
        else
        {
            double a = getValue();
            double b = ( ( RealNumber )n ).getValue();
            return ( a == b ) || ( Math.abs( a - b ) < EPSILON );
        }
    }

    public boolean greaterThan( Number n )
    {
        if( n instanceof ComplexNumber )
        {
            ComplexNumber c = ( ComplexNumber )n;
            return ( c.getIm().equals( new RealNumber( 0 ) ) && greaterThan( c.getRe() ) );
        }
        else
        {
            return ( getValue() > ( ( RealNumber )n ).getValue() );
        }
    }

    public String toString()
    {
        return String.valueOf( value );
    }
}
